// Copyright 2023 ztlcloud.com
// leovs @2023.12.12

package conf

import (
	"gitee.com/leovs/yc-go-sdk/log"
	"gitee.com/leovs/yc-go-sdk/middleware"
	"gitee.com/leovs/yc-go-sdk/middleware/validators"
	"gitee.com/leovs/yc-go-sdk/sdk"
	"gitee.com/leovs/yc-go-sdk/utils"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/template/html/v2"
	"net/http"
	"runtime"
	"time"
)

type ServerConfig struct {
	Template *struct {
		Directory string `yaml:"directory"` // 模板路径
		Extension string `yaml:"extension"` // 模板后缀
	} `yaml:"template"` // 模板路径
	ReadTimeout      time.Duration `yaml:"readTimeout"`      // 读取超时
	WriteTimeout     time.Duration `yaml:"writeTimeout"`     // 写入超时
	IdleTimeout      time.Duration `yaml:"idleTimeout"`      // 空闲超时
	ReadBufferSize   int           `yaml:"readBufferSize"`   // 读取缓冲区大小
	WriteBufferSize  int           `yaml:"writeBufferSize"`  // 写入缓冲区大小
	Prefork          bool          `yaml:"prefork"`          // 是否启用预分叉
	MaxProcs         int           `yaml:"maxProcs"`         // 最大进程数
	CaseSensitive    bool          `yaml:"caseSensitive"`    // 是否大小写敏感
	DisableKeepalive bool          `yaml:"disableKeepalive"` // 是否禁用keepalive
}

// Init 初始化配置
func (e *ServerConfig) Init(config *Settings) {
	// 初始化程序并设置运行模式
	log.Info("[%v] 版本[%v] 运行模式[%v]", config.AppName, config.Version, config.Mode)
	log.DebugMode = sdk.Runtime.IsDebug()

	fc := fiber.Config{}

	if e != nil {

		// 如果开启Prefork,设置最大进程数
		if e.Prefork {
			if e.MaxProcs > 1 && e.MaxProcs <= runtime.NumCPU() {
				runtime.GOMAXPROCS(e.MaxProcs)
			} else {
				// 如果MaxProcs <= 0,则关闭Prefork
				e.Prefork = false
			}
		}

		fc = fiber.Config{
			ReadTimeout:      e.ReadTimeout,
			WriteTimeout:     e.WriteTimeout,
			IdleTimeout:      e.IdleTimeout,
			ReadBufferSize:   e.ReadBufferSize,
			WriteBufferSize:  e.WriteBufferSize,
			Prefork:          e.Prefork,
			CaseSensitive:    e.CaseSensitive,
			DisableKeepalive: e.DisableKeepalive,
			AppName:          config.AppName,
		}

		if e.Template != nil {
			var engine *html.Engine
			directory := utils.Ternary(e.Template.Directory == "", "./views", e.Template.Directory).(string)
			extension := utils.Ternary(e.Template.Extension == "", ".html", e.Template.Extension).(string)
			if config.FS != nil {
				engine = html.NewFileSystem(http.FS(config.FS), extension)
			} else {
				engine = html.New(directory, extension)
			}
			if log.DebugMode {
				engine.Reload(true)
				engine.Debug(true)
			}
			fc.Views = engine
		}

	}

	fb := fiber.New(fc)

	sdk.Runtime.SetEngine(fb)
	validators.Init()
	middleware.InitMiddleware(fb)
}
